package com.granada.service.base;

import com.granada.behaviour.base.PermissionBehavior;
import com.granada.behaviour.interfaces.UserBehavior;
import com.granada.common.Curd;
import com.granada.entity.Ao;
import com.granada.mapper.SysUserWechatMapper;
import com.granada.service.RedisService;
import com.granada.behaviour.base.RoleBehavior;
import com.granada.behaviour.base.UserRoleBehavior;
import com.granada.constants.Constant;
import com.granada.model.common.User;
import com.granada.utils.TokenSettings;
import com.granada.vo.resp.PageVO;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;
import java.util.concurrent.TimeUnit;

public abstract class UserService<T,M> implements Curd, UserBehavior {
    public User userModel;
    public com.granada.behaviour.base.UserBehavior userBehavior;
    public PermissionBehavior permissionBehavior;
    protected Ao ao;
    public RedisService redisService;
    public RoleBehavior roleBehavior;
    public UserRoleBehavior userRoleBehavior;
    public TokenSettings tokenSettings;

    public SysUserWechatMapper sysUserWechatMapper;

    public UserService(
            User userModel,
            com.granada.behaviour.base.UserBehavior userBehavior,
            PermissionBehavior permissionBehavior,
            RoleBehavior roleBehavior,
            UserRoleBehavior userRoleBehavior,
            Ao ao
    ) {
        this.userModel = userModel;
        this.permissionBehavior = permissionBehavior;
        this.roleBehavior = roleBehavior;
        this.userBehavior = userBehavior;
        this.userRoleBehavior = userRoleBehavior;
        this.ao = ao;
    }

    @Autowired
    public void setRedisService(RedisService redisService) {
        this.redisService = redisService;
    }

    @Autowired
    public void setTokenSettings(TokenSettings tokenSettings) {
        this.tokenSettings = tokenSettings;
    }

    @Autowired
    public void setSysUserWechatMapper(SysUserWechatMapper sysUserWechatMapper) {
        this.sysUserWechatMapper = sysUserWechatMapper;
    }

    public M register() throws Exception {
        Long userId = this.userModel.add();
        return null;
    }

    ;

    public Long add() throws Exception {
        return this.userModel.add();
    }

    public void update() throws Exception {
        this.userModel.update();
        if (ao.getStatus() == 2) {
            redisService.set(Constant.ACCOUNT_LOCK_KEY + ao.id, ao.id);
        } else {
            redisService.delete(Constant.ACCOUNT_LOCK_KEY + ao.id);
        }
    }

    public void delete() throws Exception {
        this.userModel.delete();
        redisService.set(Constant.DELETED_USER_KEY + ao.id, ao.id, tokenSettings.getRefreshTokenExpireAppTime().toMillis(), TimeUnit.MILLISECONDS);
        //清空权鉴缓存
        redisService.delete(Constant.IDENTIFY_CACHE_KEY + ao.id);
    }

    public void batchDelete() throws Exception {
        this.userModel.batchDelete();
        for (Long userId : ao.ids) {
            redisService.set(Constant.DELETED_USER_KEY + userId, userId, tokenSettings.getRefreshTokenExpireAppTime().toMillis(), TimeUnit.MILLISECONDS);
            //清空权鉴缓存
            redisService.delete(Constant.IDENTIFY_CACHE_KEY + userId);
        }
    }

    public T getOne() throws Exception {
        return (T) this.userModel.getOne();
    }

    public PageVO<T> getSearchList() throws Exception {
        return (PageVO<T>) this.userModel.getSearchList();
    }

    public PageVO<T> getList() throws Exception {
        return (PageVO<T>) this.userModel.getList();
    }

    public List<T> getAll() throws Exception {
        return this.userModel.getAll();
    }

    public T getSearchOne() throws Exception {
        return (T) this.userModel.getSearchOne();
    }

    public List<T> getSearchAll() throws Exception {
        return this.userModel.getSearchAll();
    }
}
